function _in(o){return o.fadeIn();}
function _out(o) {return o.fadeOut();}
var fx_in = _in;
var fx_out = _out;

var close_text = '';
var before_ax = false;
var after_ax = false;
var debug = false;
var RELINK = true;
var waiting = "../static/images/waiting.gif";
var loading_text = 'In attesa...';
var loading_html = '<div style="position : fixed; top : 50%; left : 50%; width:300px; weight:300px; margin:-150px; padding : 20px; background : black url(\'' + waiting +'\') no-repeat right; opacity : 0.8; color : white; border-radius : 10px; -moz-border-radius : 10px; z-index:1000">' + loading_text + '</div>'; 


//costanti
var re_flash = /<div class=["']flash['"]>(.*?)<\/div>/i;
var re_script = /<script (.*?)>(.*?)<\/script>/i;
var _source = false;
var _parent = false;
var _scripts = [];
var _script = '';
var _obj = '';
var _error = false;
var _web2py = true;
var _butt = '';
var _error_flags = [
    'SD',
    'SQ',
];

function ax_replace(d){
    tgt = $(dest);
    
    //speciali per il form
    if (_source.tagName == 'FORM'){
        if (!_error){
            if (has_flag('E')) _source.reset();        
            if (has_flag('Q')) {
                if (has_flag('T',_source._source)) toggle_close(_source._source)
                else _hide($(_source).parent().hasClass('dialogue')? $(_source).parent():$(_source));
            }
        }
        else {
            if (has_flag('I')) $(_source).html(d);
            else $(_source).replaceWith(d);
            _source = _source._source;
  //          _source._target = d;
            if (_source._toggle && !has_flag('D')) _source._toggle = d;
            return;
        }
        
        _error = false;
    }
    if (has_flag('F')) tgt.after(d);
    else if (has_flag('B')) tgt.before(d);
    else if (has_flag('A')) tgt.append(d);
    else if (has_flag('P')) tgt.prepend(d);
    else if (has_flag('S')) {
        tgt.replaceWith(d);
        //aggiorno tutti i link per puntare al nuovo nodo
        if (debug && d.length > 1) alert('Warning : Flag S substituting more than one node\nMay cause relinking error.');
        $('a,form').each(function(n,a){if(a._target==dest) {a._target =d[0];}});
    }
    else if (has_flag('I')) {
        tgt.html(d);
        if (has_flag('D') && !has_flag('T'))
            tgt.find('div.dialogue_close_button').click(function(e){
                return toggle_close(e.currentTarget._source);
            })[0]._source = _error?_source._source:_source;
    }
    if (has_flag('M')) _source._target = d;
    if (has_flag('TD')) _source._toggle = has_flag('I')?tgt:d;
    //apparizione
    if (!has_flag('IS')) _show(d);
}

function error(res){
    $(_source).removeClass('working');
    dest.innerHTML = res.responseText;
    to_remove.remove();
    $(dest).addClass('ajax_error');
};

function ax_res(data,res,xhr){
    _butt = '<DIV class="dialogue_close_button">' + close_text + '</DIV>';
    fls = data.match(re_flash);
    if (fls){
        flash(fls[1]);
        data = data.replace(re_flash,'');
    }
    if (has_flag('D')) data = '<DIV class="dialogue">' + data + '</DIV>';
    d = $(data);
    _error = d.find('.error').length;
    if ((has_flag('D') && !has_flag('T')) || (_error && $(_source).parent().hasClass('dialogue') && !has_flag('T',_source._source))) {
        if (has_flag('I')){
            data = data.slice(0,22) + _butt + data.slice(22);
        }
        butt = $(_butt);
        d.prepend(butt);
        butt.click(function(e){
            return toggle_close(e.currentTarget._source);
        })[0]._source = _error?_source._source:_source;
    }
    _script = '';
    d.find('script').each(on_script);   
    d.each(function(n,x){if (x.tagName && x.tagName == 'SCRIPT') on_script(0,x);});
    d = d.filter(function(n,x){return !((x.tagName == 'SCRIPT') && (x.text.length>1));});
    ax_replace(has_flag('I')?data:d);
    
    //finalizzo
    $(_source).removeClass('working');
    to_remove.remove();
    ax(has_flag('I')?_target:d);
    if (!has_flag('I')) eval(_script);
    if (after_ax) after_ax(d);
}

function _hide(o){
    _obj = o;
    if (has_flag('O')) fx_out(o);
    else $.when(fx_out(o)).then(function(c){c.remove();});
    src = o[0]._source;
//    if (fx_out != '') eval('$.when(_obj.' + fx_out + ').then(function(){_obj.remove();});');
//    else o.hide();
}

function _show(o){
    _obj = o;
    o.hide();
    fx_in(o);
//    if (fx_in != '') eval('_obj.' + fx_in + ';');
//    else o.show();
}

function ajax(url,s,dd){
    if (s) _source = s;
    if (dd) dest = dd;
    $(_source).addClass('working');
    to_remove = $(loading_html);
    $(dest).append(to_remove);
    $.ajax({url:url,
        error:error,
        success:ax_res
    });
}

function bind_parent_source(n,tag){
    tag._source = _source;
    tag._parent = _parent;
    tag._target = find_target(tag);
}

function relink(l){
    if (!RELINK) return l;
    if (l){
        ret = '';
            ls = l.split('/');
        for (a=1;a<ls.length;a++){
            if (a!=3)
                ret += '/' + ls[a];
            else
                ret += '/a_' + ls[a];
        }
        return ret;
    }
}

function find_me(o){
    p = o.parentNode.children;
    a=0;
    while((a < p.length) && (p[a]!=o))
        a++;
    return a;
}

function find_parent(o){
    t = o;
    if (o.hasAttribute('par')){
        for (a=0;a<parseInt(o.getAttribute('par'));a++)
            t = t.parentNode;
        return t;
        }
    else
        return t._parent?t._parent:t;
}

function has_flag(flag,o,all){
    if (!o) o = _source;
    if (flag.length > 1) return all?
        flag.split('').every(function(a,b,c){return has_flag(a,o);}):
        flag.split('').some(function(a,b,c){return has_flag(a,o);});
    try{
        return (-1 != o.getAttribute('flags').indexOf(flag)); 
    }
    catch (ex){return false;}
}

function set_flag(flag,obj){
    if(!has_flag(flag,obj)){
        if (obj.hasAttribute('flags'))
            obj.setAttribute('flags',obj.getAttribute('flags') + flag);
        else
            obj.setAttribute('flags',flag);
    }
}

function find_target(o){
    if (o._target) return o._target;
    if (o.hasAttribute('path')){
        path = o.getAttribute('path').split(',');
        l = path[path.length - 1].toUpperCase();
        if (l == '_') l= 'S';
        if (l.match(/[A-Z]/)) {
            path = path.slice(0,path.length - 1);
            l.split('').forEach(function(a){set_flag(a,o);});
        }
        target = o;
        p = parseInt(path[0]);
        if ($(o).hasClass('dialogue')) p++;
        for (a = 0 ; a < p ; a++){
            target = target.parentNode;
        }
        if (path.length >1){
            par = parseInt(path[1]);
            f = find_me(target);
            target = target.parentNode.children[f + par];
            if (path.length > 2)
                for (b=2;b<path.length;b++){
                    target = target.children[path[b]];
                }
            return target;
        }
    }
    if (!o.hasAttribute('r'))
        o.setAttribute('r','parent');
    if (o.getAttribute('r')!='parent') return has_flag('X',o)?
        $("#" + o.getAttribute('r'))[0]:
        $(o._parent).find("#" + o.getAttribute('r'))[0];
    else return find_parent(o);    
    return target;
}

function on_tag(n,tag){
    if (tag.tagName == 'FORM')  on_form(0,tag);
    else if (tag.tagName == 'A') on_link(0,tag);
    else if (tag.tagName == 'DIV'){
        if ($(tag).hasClass('error')) on_error(0,tag);
    }
}

function on_form(n,form){
    if (has_flag('R',form))return ;
    set_flag('X',form);
    bind_parent_source(n,form);
    if (_source.hasAttribute('sflags')) form.setAttribute('flags',_source.getAttribute('sflags'));
    if (_source.hasAttribute('spath')) form.setAttribute('path',_source.getAttribute('spath'));
    if (_source.hasAttribute('sr')) form.setAttribute('r',_source.getAttribute('sr'));
    if (has_flag('E')) set_flag('E',form)
    if (has_flag('Q')) set_flag('Q',form)
    if (!has_flag('ABFSP',form)) set_flag('I',form);
    if (!form.hasAttribute('action')||('' == form.getAttribute('action'))) 
        form.setAttribute('ajax', this._source.getAttribute('ajax'));
    else
        form.setAttribute('ajax',relink(form.getAttribute('action')));

    $(form).submit(function(){
        url = this.getAttribute('ajax') + '?' + $(this).serialize();
        if ((form.hasAttribute('question')) && (!confirm(form.getAttribute('question')))) return false;
        ajax(url,form,this._target);
        return false;
    });
}

function on_link(n,link,t){
    if (!has_flag('R',link)){
        link._open = false;
        link.setAttribute('ajax', relink(link.getAttribute('href')));
        link.removeAttribute('href');
        bind_parent_source(n,link);
        if (has_flag('O',link)) set_flag('T',link);
        if (!has_flag('ABFSP',link)) set_flag('I',link);
        $(link).click(function(l){
            q = $(link).attr('question');
            if (q && !confirm(q)) return false; 
            _target = find_target(link);
            if (has_flag('T',this)){
                $('a').each(function(n,a){if ((a._target == this._target) && has_flag('T',a)) a._open = this._open;});
                if (this._open) return toggle_close(this);
                else toggle_open(this);
                if (has_flag('O') && this._toggle && this._open) return _show(this._toggle);
            }
            //non apre piu di un dialog
            else if (has_flag('D',this)) {
                if (this._open) return false;
                else this._open = true;
            }
            ajax($(link).attr('ajax'),link,_target);
        });
    }
}

function toggle_open(o){
    o._open = true;
    $(o).addClass('opened');    
}

function toggle_close(o){
    if (has_flag('IS') && !has_flag('O')) $(o._target).html('');
    else _hide(o._toggle);
    o._open = false;
    $(o).removeClass('opened');
    return false;
}

function flash(text){
    f = $('.flash')[0];
    $(f).hide();
    f.innerHTML = text;
    $(f).slideDown(400);
}

function on_flash(n,_flash){
    flash(_flash.innerHTML);
    $(_flash).remove();
}

function on_error(n,error){
    e = $(error);
    e.show().hide().slideDown('slow');
    e.click(function(){$(this).slideUp(400);});
}

function on_script(n,scr){
    if (scr.hasAttribute('src')){
        if (-1 != _scripts.indexOf(scr.getAttribute('src'))) $(scr).remove();    
        else _scripts.push(scr.getAttribute('src')); 
    }else{
        if (scr.text.length > 1){
            _script += scr.text;
            $(scr).remove();
        }
    }
}

function on_date(o){
    $(o);
}

function ax(tgt){    
    if (!_source) {
        _source = tgt;
        $(_source).attr('ajax',document.URL);
    }
    _parent = tgt;
    if (before_ax && before_ax(tgt)) return;
    tgt = $(tgt);
    tgt.each(on_tag);
    tgt.find("a").each(on_link);
    tgt.find("form").each(on_form);
    tgt.find('div.error').each(on_error);
    tgt.find('input.date').each(on_date);
//    tgt.find('script').each(on_script);
    if (debug){
        function hIn(e){
            th = e.currentTarget;
            if (this.tagName == 'INPUT')
                th = this.form
            t = find_target(th);
            if (t){
                t.obor = $(t).css('border');
                path = th.getAttribute('path')
                if (!path)
                    path = '0';
                color = 'black'
                if (has_flag('A',th)) color = 'green';
                else if (has_flag('A',th)) color = 'red';
                else if (has_flag('F',th)) color = 'blue';
                else if (has_flag('B',th)) color = 'orange';
                else if (has_flag('S',th)) color = 'cyan';
                else color = 'yellow';
                jQuery(t).css('border',color + ' 2px solid');
            }else $(th).addClass('error');
        }
        function hOut(e){
            th = e.currentTarget;
            if ((th.tagName == 'INPUT') || (th.tagName == 'BUTTON'))
                th = th.form
            t = find_target(th);
            if (t) jQuery(t).css('border',t.obor);
        }
        tgt.find('[ajax]').each(function(a,t){
            t.setAttribute('title',t.getAttribute('ajax') + ' --- ' + (t.hasAttribute('flags')?t.getAttribute('flags'):''));
            $(t).hover(hIn,hOut);
            for (a=0;a<_error_flags.length;a++)
                if ((count_flags(t,'ABFPIS') > 1) || (has_flag(_error_flags[a],t,true))){
                    $(t).addClass('error');
                    t.setAttribute('title',t.getAttribute('title') + ' : Incompatibles flags');
                }
        });
        tgt.find('input').hover(hIn,hOut);
    }
}

function count_flags(o,flags){
    len = 0
    f = o.getAttribute('flags');
    for (a=0;a<flags.length;a++)
        if (-1 < f.indexOf(flags[a])) len++;
    return len;
}

$(document).ready(function(){
    f = $('.flash');
    f.hide();
    if (f.html().length > 0)
        f.slideDown();
    f.click(function(){
        $(this).slideUp();
    });
    $('.ax_start').each(function(n,a){ax(a);});
});
